home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmmix-1.1 / widget.c < prev    next >
C/C++ Source or Header  |  1995-07-05  |  32KB  |  1,162 lines

  1. /*
  2.  *   xmmix - Motif(tm) Audio Mixer
  3.  *
  4.  *   Copyright (C) 1995  Ti Kan
  5.  *   E-mail: ti@amb.org
  6.  *
  7.  *   This program is free software; you can redistribute it and/or modify
  8.  *   it under the terms of the GNU General Public License as published by
  9.  *   the Free Software Foundation; either version 2 of the License, or
  10.  *   (at your option) any later version.
  11.  *
  12.  *   This program is distributed in the hope that it will be useful,
  13.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *   GNU General Public License for more details.
  16.  *
  17.  *   You should have received a copy of the GNU General Public License
  18.  *   along with this program; if not, write to the Free Software
  19.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  *
  21.  */
  22. #ifndef LINT
  23. static char *_widget_c_ident_ = "@(#)widget.c    2.5 95/05/12";
  24. #endif
  25.  
  26. #include "appenv.h"
  27. #include "widget.h"
  28. #include "mixer.h"
  29. #include "xmmix.xbm"
  30.  
  31.  
  32. extern appdata_t    app_data;
  33. extern widgets_t    widgets;
  34. extern int        maxdevs;
  35.  
  36. #define CTL_DISTANCE    48
  37.  
  38.  
  39. #define PD_FILE_LOAD    0
  40. #define PD_FILE_SAVE    1
  41. #define PD_FILE_SEP    2
  42. #define PD_FILE_EXIT    3
  43.  
  44. STATIC btinfo_t        file_btinfo[] = {
  45.     { NULL, "Load...", "loadButton",    "l",  "L"  },
  46.     { NULL, "Save...", "saveButton",    "s",  "S"  },
  47.     { NULL, NULL,      "fileSeparator", NULL, NULL },
  48.     { NULL, "Exit",    "exitButton",    "x",  "x"  },
  49.     { NULL, NULL,      NULL,            NULL, NULL },
  50. };
  51.  
  52. #define PD_OPTS_RESET    0
  53.  
  54. STATIC btinfo_t        options_btinfo[] = {
  55.     { NULL, "Reset", "resetButton", "r",  "R" },
  56.     { NULL, NULL,    NULL,          NULL, NULL },
  57. };
  58.  
  59. #define PD_HELP_MANPG    0
  60. #define PD_HELP_ABOUT    1
  61.  
  62. STATIC btinfo_t        help_btinfo[] = {
  63.     { NULL, "Man page...", "manPageButton", "m",  "M" },
  64.     { NULL, "About...",    "aboutButton",   "a",  "A" },
  65.     { NULL, NULL,          NULL,            NULL, NULL },
  66. };
  67.  
  68. STATIC pdinfo_t        file_pd = {
  69.     NULL, "File",    "file",    "f", "F", file_btinfo
  70. };
  71.  
  72. STATIC pdinfo_t        opts_pd = {
  73.     NULL, "Options", "options", "o", "O", options_btinfo
  74. };
  75.  
  76. STATIC pdinfo_t        help_pd = {
  77.     NULL, "Help",    "help",    "h", "H", help_btinfo
  78. };
  79.  
  80. STATIC slinfo_t        slinfo[] = {
  81.     {    /* 0 */
  82.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  83.     "Master", "master", CTL_OUTPUT, 17, TRUE, FALSE
  84.     },
  85.     {    /* 1 */
  86.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  87.     "Bass", "bass", CTL_MISC, 10, TRUE, FALSE
  88.     },
  89.     {    /* 2 */
  90.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  91.     "Treble", "treble", CTL_MISC, 11, TRUE, FALSE
  92.     },
  93.     {    /* 3 */
  94.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  95.     "Synth", "synth", CTL_INPUT, 1, TRUE, TRUE
  96.     },
  97.     {    /* 4 */
  98.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  99.     "PCM", "pcm", CTL_INPUT, 2, TRUE, TRUE
  100.     },
  101.     {    /* 5 */
  102.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  103.     "Speaker", "speaker", CTL_OUTPUT, 16, TRUE, FALSE
  104.     },
  105.     {    /* 6 */
  106.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  107.     "Line", "line", CTL_INPUT, 4, TRUE, TRUE
  108.     },
  109.     {    /* 7 */
  110.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  111.     "Mic", "mic", CTL_INPUT, 8, TRUE, TRUE
  112.     },
  113.     {    /* 8 */
  114.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  115.     "CD", "cd", CTL_INPUT, 9, TRUE, TRUE
  116.     },
  117.     {    /* 9 */
  118.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  119.     "Rec Mon", "recmon", CTL_OUTPUT, 12, TRUE, FALSE
  120.     },
  121.     {    /* 10 */
  122.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  123.     "Alt PCM", "altpcm", CTL_INPUT, 3, TRUE, TRUE
  124.     },
  125.     {    /* 11 */
  126.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  127.     "Rec Out", "recout", CTL_OUTPUT, 13, TRUE, FALSE
  128.     },
  129.     {    /* 12 */
  130.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  131.     "In Gain", "igain", CTL_MISC, 14, TRUE, FALSE
  132.     },
  133.     {    /* 13 */
  134.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  135.     "Out Gain", "ogain", CTL_MISC, 15, TRUE, FALSE
  136.     },
  137.     {    /* 14 */
  138.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  139.     "Line-1", "line1", CTL_INPUT, 5, TRUE, TRUE
  140.     },
  141.     {    /* 15 */
  142.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  143.     "Line-2", "line2", CTL_INPUT, 6, TRUE, TRUE
  144.     },
  145.     {    /* 16 */
  146.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  147.     "Line-3", "line3", CTL_INPUT, 7, TRUE, TRUE
  148.     },
  149.     {    /* 17 */
  150.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  151.     NULL, NULL, 0, 0, FALSE, FALSE
  152.     },
  153.     {    /* 18 */
  154.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  155.     NULL, NULL, 0, 0, FALSE, FALSE
  156.     },
  157.     {    /* 19 */
  158.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  159.     NULL, NULL, 0, 0, FALSE, FALSE
  160.     },
  161.     {    /* 20 */
  162.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  163.     NULL, NULL, 0, 0, FALSE, FALSE
  164.     },
  165.     {    /* 21 */
  166.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  167.     NULL, NULL, 0, 0, FALSE, FALSE
  168.     },
  169.     {    /* 22 */
  170.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  171.     NULL, NULL, 0, 0, FALSE, FALSE
  172.     },
  173.     {    /* 23 */
  174.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  175.     NULL, NULL, 0, 0, FALSE, FALSE
  176.     },
  177.     {    /* 24 */
  178.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  179.     NULL, NULL, 0, 0, FALSE, FALSE
  180.     },
  181.     {    /* 25 */
  182.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  183.     NULL, NULL, 0, 0, FALSE, FALSE
  184.     },
  185.     {    /* 26 */
  186.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  187.     NULL, NULL, 0, 0, FALSE, FALSE
  188.     },
  189.     {    /* 27 */
  190.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  191.     NULL, NULL, 0, 0, FALSE, FALSE
  192.     },
  193.     {    /* 28 */
  194.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  195.     NULL, NULL, 0, 0, FALSE, FALSE
  196.     },
  197.     {    /* 29 */
  198.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  199.     NULL, NULL, 0, 0, FALSE, FALSE
  200.     },
  201.     {    /* 30 */
  202.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  203.     NULL, NULL, 0, 0, FALSE, FALSE
  204.     },
  205.     {    /* 31 */
  206.     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  207.     NULL, NULL, 0, 0, FALSE, FALSE
  208.     }
  209. };
  210.  
  211. STATIC XmString        xs_lock,
  212.             xs_rec,
  213.             xs_left,
  214.             xs_right;
  215.  
  216. STATIC Atom        delw;
  217.  
  218.  
  219. /***********************
  220.  *  internal routines  *
  221.  ***********************/
  222.  
  223. /*
  224.  * Widget-related functions
  225.  */
  226.  
  227. /*
  228.  * create_pdmnu
  229.  *    Create a pulldown menu
  230.  *
  231.  * Args:
  232.  *    parent - The parent widget
  233.  *    pd - The pulldown menu info structure
  234.  *
  235.  * Return:
  236.  *    The menu widget
  237.  */
  238. STATIC Widget
  239. create_pdmnu(Widget parent, pdinfo_t *pd)
  240. {
  241.     int        i,
  242.             n;
  243.     Arg        arg[10];
  244.     XmString    xs;
  245.     XmString    xs_acc;
  246.     char        wname[STR_BUF_SZ];
  247.     Widget        ret_widget;
  248.  
  249.     /* Create File pulldown menu */
  250.     sprintf(wname, "%sMenu", pd->name);
  251.     ret_widget = XmCreatePulldownMenu(parent, wname, NULL, 0);
  252.  
  253.     for (i = 0; pd->btip[i].name != NULL; i++) {
  254.         n = 0;
  255.         if (pd->btip[i].label == NULL) {
  256.             /* Separator */
  257.             pd->btip[i].widget = XmCreateSeparator(
  258.                 ret_widget, pd->btip[i].name, NULL, 0
  259.             );
  260.             XtManageChild(pd->btip[i].widget);
  261.         }
  262.         else {
  263.             /* Button */
  264.             if (pd->btip[i].label != NULL) {
  265.                 xs = XmStringCreateSimple(pd->btip[i].label);
  266.                 XtSetArg(arg[n], XmNlabelString, xs); n++;
  267.             }
  268.  
  269.             if (pd->btip[i].acc != NULL) {
  270.                 xs_acc = XmStringCreateSimple(pd->btip[i].acc);
  271.                 XtSetArg(arg[n], XmNaccelerator, xs_acc); n++;
  272.             }
  273.  
  274.             if (pd->btip[i].mne != NULL) {
  275.                 XtSetArg(arg[n], XmNmnemonic,
  276.                      XStringToKeysym(pd->btip[i].mne)); n++;
  277.             }
  278.  
  279.             pd->btip[i].widget = XmCreatePushButton(
  280.                 ret_widget, pd->btip[i].name, arg, n
  281.             );
  282.             XtManageChild(pd->btip[i].widget);
  283.  
  284.             if (pd->btip[i].label != NULL)
  285.                 XmStringFree(xs);
  286.             if (pd->btip[i].acc != NULL)
  287.                 XmStringFree(xs_acc);
  288.         }
  289.     }
  290.  
  291.     /* Create cascade button as menu activator */
  292.     sprintf(wname, "%sButton", pd->name);
  293.  
  294.     n = 0;
  295.     if (pd->label != NULL) {
  296.         xs = XmStringCreateSimple(pd->label);
  297.         XtSetArg(arg[n], XmNlabelString, xs); n++;
  298.     }
  299.     if (pd->acc != NULL) {
  300.         xs_acc = XmStringCreateSimple(pd->acc);
  301.         XtSetArg(arg[n], XmNaccelerator, xs_acc); n++;
  302.     }
  303.     if (pd->mne != NULL) {
  304.         XtSetArg(arg[n], XmNmnemonic, XStringToKeysym(pd->mne)); n++;
  305.     }
  306.  
  307.     XtSetArg(arg[n], XmNsubMenuId, ret_widget); n++;
  308.     pd->widget = XmCreateCascadeButton(parent, wname, arg, n);
  309.     XtManageChild(pd->widget);
  310.  
  311.     if (pd->label != NULL)
  312.         XmStringFree(xs);
  313.     if (pd->acc != NULL)
  314.         XmStringFree(xs_acc);
  315.  
  316.     return (ret_widget);
  317. }
  318.  
  319.  
  320. /*
  321.  * create_vert_controls
  322.  *    Create a group of mixer controls including the vertical slider
  323.  *    and associated toggle buttons and labels.
  324.  *
  325.  * Args:
  326.  *    m - Pointer to the main widgets structure
  327.  *    dev - The mixer control device index
  328.  *    y1 - The top reference position (percent)
  329.  *    y2 - The bottom reference position (percent)
  330.  *    pos - The display position number
  331.  *    tot - Total number of controls to be displayed
  332.  *
  333.  * Return:
  334.  *    Nothing
  335.  */
  336. STATIC void
  337. create_vert_controls(widgets_t *m, int dev, int y1, int y2, int pos, int tot)
  338. {
  339.     int        x,
  340.             n;
  341.     Arg        arg[20];
  342.     char        wname[STR_BUF_SZ];
  343.     XmString    xs;
  344.  
  345.     x = CTL_DISTANCE * pos;
  346.  
  347.     /* Right slider */
  348.     sprintf(wname, "%sRightScale", slinfo[dev].name);
  349.     n = 0;
  350.     XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
  351.     XtSetArg(arg[n], XmNrightAttachment, XmATTACH_NONE); n++;
  352.     XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  353.     XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
  354.     XtSetArg(arg[n], XmNleftOffset, x); n++;
  355.     XtSetArg(arg[n], XmNtopPosition, y1); n++;
  356.     XtSetArg(arg[n], XmNbottomPosition, y2); n++;
  357.     XtSetArg(arg[n], XmNshowValue, False); n++;
  358.     XtSetArg(arg[n], XmNorientation, XmVERTICAL); n++;
  359.     XtSetArg(arg[n], XmNprocessingDirection, XmMAX_ON_TOP); n++;
  360.     XtSetArg(arg[n], XmNminimum, 0); n++;
  361.     XtSetArg(arg[n], XmNmaximum, 100); n++;
  362.     XtSetArg(arg[n], XmNhighlightOnEnter, True); n++;
  363.     slinfo[dev].widget_r = XmCreateScale(m->form, wname, arg, n);
  364.     XtManageChild(slinfo[dev].widget_r);
  365.  
  366.     /* Left slider */
  367.     sprintf(wname, "%sLeftScale", slinfo[dev].name);
  368.     n = 0;
  369.     XtSetArg(arg[n], XmNleftAttachment, XmATTACH_NONE); n++;
  370.     XtSetArg(arg[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
  371.     XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  372.     XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
  373.     XtSetArg(arg[n], XmNrightWidget, slinfo[dev].widget_r); n++;
  374.     XtSetArg(arg[n], XmNtopPosition, y1); n++;
  375.     XtSetArg(arg[n], XmNbottomPosition, y2); n++;
  376.     XtSetArg(arg[n], XmNshowValue, False); n++;
  377.     XtSetArg(arg[n], XmNorientation, XmVERTICAL); n++;
  378.     XtSetArg(arg[n], XmNprocessingDirection, XmMAX_ON_TOP); n++;
  379.     XtSetArg(arg[n], XmNminimum, 0); n++;
  380.     XtSetArg(arg[n], XmNmaximum, 100); n++;
  381.     XtSetArg(arg[n], XmNhighlightOnEnter, True); n++;
  382.     slinfo[dev].widget_l = XmCreateScale(m->form, wname, arg, n);
  383.     XtManageChild(slinfo[dev].widget_l);
  384.         
  385.     /* Left label */
  386.     sprintf(wname, "%sLeftLabel", slinfo[dev].name);
  387.     n = 0;
  388.     XtSetArg(arg[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  389.     XtSetArg(arg[n], XmNrightAttachment, XmATTACH_NONE); n++;
  390.     XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  391.     XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  392.     XtSetArg(arg[n], XmNleftWidget, slinfo[dev].widget_l); n++;
  393.     XtSetArg(arg[n], XmNtopPosition, y1 - 4); n++;
  394.     XtSetArg(arg[n], XmNbottomWidget, slinfo[dev].widget_l); n++;
  395.     XtSetArg(arg[n], XmNlabelString, xs_left); n++;
  396.     slinfo[dev].widget_lbl_l = XmCreateLabel(
  397.         m->form, wname, arg, n
  398.     );
  399.     XtManageChild(slinfo[dev].widget_lbl_l);
  400.  
  401.     /* Right label */
  402.     sprintf(wname, "%sRightLabel", slinfo[dev].name);
  403.     n = 0;
  404.     XtSetArg(arg[n], XmNleftAttachment, XmATTACH_NONE); n++;
  405.     XtSetArg(arg[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  406.     XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  407.     XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  408.     XtSetArg(arg[n], XmNrightWidget, slinfo[dev].widget_r); n++;
  409.     XtSetArg(arg[n], XmNtopPosition, y1 - 4); n++;
  410.     XtSetArg(arg[n], XmNbottomWidget, slinfo[dev].widget_r); n++;
  411.     XtSetArg(arg[n], XmNlabelString, xs_right); n++;
  412.     slinfo[dev].widget_lbl_r = XmCreateLabel(
  413.         m->form, wname, arg, n
  414.     );
  415.     XtManageChild(slinfo[dev].widget_lbl_r);
  416.  
  417.     /* Slider label */
  418.     sprintf(wname, "%sLabel", slinfo[dev].name);
  419.     xs = XmStringCreateSimple(slinfo[dev].label);
  420.     n = 0;
  421.     XtSetArg(arg[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  422.     XtSetArg(arg[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  423.     XtSetArg(arg[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  424.     XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  425.     XtSetArg(arg[n], XmNleftWidget, slinfo[dev].widget_lbl_l); n++;
  426.     XtSetArg(arg[n], XmNrightWidget, slinfo[dev].widget_lbl_r); n++;
  427.     XtSetArg(arg[n], XmNleftOffset, -4); n++;
  428.     XtSetArg(arg[n], XmNrightOffset, -4); n++;
  429.     XtSetArg(arg[n], XmNtopWidget, m->menu_bar); n++;
  430.     XtSetArg(arg[n], XmNtopOffset, 3); n++;
  431.     XtSetArg(arg[n], XmNbottomWidget, slinfo[dev].widget_lbl_l); n++;
  432.     XtSetArg(arg[n], XmNlabelString, xs); n++;
  433.     slinfo[dev].widget_lbl = XmCreateLabel(
  434.         m->form, slinfo[dev].name, arg, n
  435.     );
  436.     XtManageChild(slinfo[dev].widget_lbl);
  437.     XmStringFree(xs);
  438.  
  439.     /* Lock button */
  440.     sprintf(wname, "%sLockButton", slinfo[dev].name);
  441.     n = 0;
  442.     XtSetArg(arg[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  443.     XtSetArg(arg[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  444.     XtSetArg(arg[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  445.     XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++;
  446.     XtSetArg(arg[n], XmNleftWidget, slinfo[dev].widget_l); n++;
  447.     XtSetArg(arg[n], XmNrightWidget, slinfo[dev].widget_r); n++;
  448.     XtSetArg(arg[n], XmNtopWidget, slinfo[dev].widget_l); n++;
  449.     XtSetArg(arg[n], XmNlabelString, xs_lock); n++;
  450.     slinfo[dev].widget_lock_btn = XmCreateToggleButton(
  451.         m->form, wname, arg, n
  452.     );
  453.     XtManageChild(slinfo[dev].widget_lock_btn);
  454.  
  455.     /* Record selector buttons */
  456.     if (slinfo[dev].recsupp) {
  457.         sprintf(wname, "%sRecButton", slinfo[dev].name);
  458.         n = 0;
  459.         XtSetArg(arg[n], XmNleftAttachment,
  460.              XmATTACH_OPPOSITE_WIDGET); n++;
  461.         XtSetArg(arg[n], XmNrightAttachment,
  462.              XmATTACH_OPPOSITE_WIDGET); n++;
  463.         XtSetArg(arg[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  464.         XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++;
  465.         XtSetArg(arg[n], XmNleftWidget, slinfo[dev].widget_l); n++;
  466.         XtSetArg(arg[n], XmNrightWidget, slinfo[dev].widget_r); n++;
  467.         XtSetArg(arg[n], XmNtopWidget,
  468.              slinfo[dev].widget_lock_btn); n++;
  469.         XtSetArg(arg[n], XmNlabelString, xs_rec); n++;
  470.         slinfo[dev].widget_rec_btn = XmCreateToggleButton(
  471.             m->form, wname, arg, n
  472.         );
  473.         XtManageChild(slinfo[dev].widget_rec_btn);
  474.     }
  475. }
  476.  
  477.  
  478. /*
  479.  * bm_to_px
  480.  *    Convert a bitmap into a pixmap.
  481.  *
  482.  * Args:
  483.  *    w - A widget the pixmap should be associated with
  484.  *    bits - Pointer to the raw bitmap data
  485.  *    width, height - The resultant pixmap dimensions
  486.  *
  487.  * Return:
  488.  *    The pixmap ID, or NULL if failure.
  489.  */
  490. Pixmap
  491. bm_to_px(Widget w, void *bits, int width, int height, int depth)
  492. {
  493.     Display        *display = XtDisplay(w);
  494.     Window        window     = XtWindow(w);
  495.     int        screen     = DefaultScreen(display);
  496.     GC        pixmap_gc;
  497.     XGCValues    val;
  498.     Pixmap        tmp_bitmap;
  499.     static Pixmap    ret_pixmap;
  500.  
  501.     tmp_bitmap = XCreateBitmapFromData(
  502.         display, window, (char *) bits, width, height
  503.     );
  504.     if (tmp_bitmap == (Pixmap) NULL)
  505.         return ((Pixmap) NULL);
  506.  
  507.     if (depth == 1) {
  508.         ret_pixmap = tmp_bitmap;
  509.         return (ret_pixmap);
  510.     }
  511.  
  512.     /* Create pixmap with depth */
  513.     ret_pixmap = XCreatePixmap(display, window, width, height, depth);
  514.     if (ret_pixmap == (Pixmap) NULL)
  515.         return ((Pixmap) NULL);
  516.  
  517.     /* Allocate colors for pixmap if on color screen */
  518.     if (DisplayCells(display, screen) > 2) {
  519.         /* Get pixmap color configuration */
  520.         XtVaGetValues(w,
  521.             XmNforeground, &val.foreground,
  522.             XmNbackground, &val.background,
  523.             NULL
  524.         );
  525.  
  526.         /* Create GC for pixmap */
  527.         pixmap_gc = XCreateGC(
  528.             display, window, GCForeground | GCBackground, &val
  529.         );
  530.     }
  531.     else
  532.         pixmap_gc = DefaultGC(display, screen);
  533.         
  534.     /* Copy bitmap into pixmap */
  535.     XCopyPlane(display, tmp_bitmap, ret_pixmap, pixmap_gc,
  536.            0, 0, width, height, 0, 0, 1);
  537.  
  538.     /* No need for the bitmap any more, so free it */
  539.     XFreePixmap(display, tmp_bitmap);
  540.  
  541.     return (ret_pixmap);
  542. }
  543.  
  544.  
  545. /***********************
  546.  *   public routines   *
  547.  ***********************/
  548.  
  549.  
  550. /*
  551.  * widget_init
  552.  *    Initialize widget-related structures.
  553.  *
  554.  * Args:
  555.  *    m - Pointer to the main widgets structure
  556.  *
  557.  * Return:
  558.  *    Nothing
  559.  */
  560. void
  561. widget_init(widgets_t *m)
  562. {
  563.     /* Initialize structures */
  564.     m->sl = slinfo;
  565.     m->file_pd = &file_pd;
  566.     m->opts_pd = &opts_pd;
  567.     m->help_pd = &help_pd;
  568. }
  569.  
  570.  
  571. /*
  572.  * create_widgets
  573.  *    Top-level function to create all widgets.
  574.  *
  575.  * Args:
  576.  *    m - Pointer to the main widgets structure
  577.  *
  578.  * Return:
  579.  *    Nothing
  580.  */
  581. void
  582. create_widgets(widgets_t *m)
  583. {
  584.     int        i, j, k, n,
  585.             ctls,
  586.             form_width;
  587.     Arg        arg[20];
  588.     char        wname[STR_BUF_SZ],
  589.             str[STR_BUF_SZ];
  590.     XmString    xs;
  591.  
  592.     /* Count the number of slider controls we will display */
  593.     for (i = 0, ctls = 0; i < maxdevs; i++) {
  594.         if (slinfo[i].supp)
  595.             ctls++;
  596.     }
  597.  
  598.     /* Create compound strings that will be used repetitively */
  599.     xs_left = XmStringCreateSimple("L");
  600.     xs_right = XmStringCreateSimple("R");
  601.     xs_lock = XmStringCreateSimple("lock");
  602.     xs_rec = XmStringCreateSimple("rec");
  603.  
  604.     /* Create form widget as container */
  605.     if ((form_width = (ctls + 1) * CTL_DISTANCE) < 300)
  606.         form_width = 300;
  607.     n = 0;
  608.     XtSetArg(arg[n], XmNwidth, form_width); n++;
  609.     XtSetArg(arg[n], XmNheight, 320); n++;
  610.     XtSetArg(arg[n], XmNresizePolicy, XmRESIZE_NONE); n++;
  611.     m->form = XmCreateForm(m->toplevel, "mainForm", arg, n);
  612.     XtManageChild(m->form);
  613.  
  614.     /* Create logo label */
  615.     n = 0;
  616.     XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
  617.     XtSetArg(arg[n], XmNrightAttachment, XmATTACH_NONE); n++;
  618.     XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  619.     XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++;
  620.     XtSetArg(arg[n], XmNleftOffset, (form_width/2) - (xmmix_width/2)); n++;
  621.     XtSetArg(arg[n], XmNtopPosition, 88); n++;
  622.     XtSetArg(arg[n], XmNlabelType, XmPIXMAP); n++;
  623.     XtSetArg(arg[n], XmNmarginHeight, 0); n++;
  624.     XtSetArg(arg[n], XmNmarginWidth, 0); n++;
  625.     XtSetArg(arg[n], XmNhighlightThickness, 0); n++;
  626.     XtSetArg(arg[n], XmNwidth, xmmix_width); n++;
  627.     XtSetArg(arg[n], XmNheight, xmmix_height); n++;
  628.     m->logolbl = XmCreateLabel(m->form, "logoLabel", arg, n);
  629.     XtManageChild(m->logolbl);
  630.  
  631.     /* Create menu bar */
  632.     n = 0;
  633.     XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
  634.     XtSetArg(arg[n], XmNrightAttachment, XmATTACH_FORM); n++;
  635.     XtSetArg(arg[n], XmNtopAttachment, XmATTACH_FORM); n++;
  636.     XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++;
  637.     m->menu_bar = XmCreateMenuBar(m->form, "menuBar", arg, n);
  638.     XtManageChild(m->menu_bar);
  639.  
  640.     /* Create File pulldown menu */
  641.     m->file_mnu = create_pdmnu(m->menu_bar, &file_pd);
  642.  
  643.     /* Create Options pulldown menu */
  644.     m->options_mnu = create_pdmnu(m->menu_bar, &opts_pd);
  645.  
  646.     /* Create Help pulldown menu */
  647.     m->help_mnu = create_pdmnu(m->menu_bar, &help_pd);
  648.     XtVaSetValues(m->menu_bar,
  649.         XmNmenuHelpWidget, help_pd.widget,
  650.         NULL
  651.     );
  652.  
  653.     /* Create all sliders and associated labels and buttons */
  654.     for (j = 1, k = 0; j <= MAXDEVS; j++) {
  655.         for (i = 0; i < maxdevs; i++) {
  656.             if (j == slinfo[i].order && slinfo[i].supp) {
  657.                 create_vert_controls(m, i, 22, 70, ++k, ctls);
  658.             }
  659.         }
  660.     }
  661.  
  662.     /* Horizontal separator */
  663.     n = 0;
  664.     XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
  665.     XtSetArg(arg[n], XmNrightAttachment, XmATTACH_FORM); n++;
  666.     XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  667.     XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++;
  668.     XtSetArg(arg[n], XmNtopPosition, 84); n++;
  669.     XtSetArg(arg[n], XmNleftOffset, 1); n++;
  670.     XtSetArg(arg[n], XmNrightOffset, 1); n++;
  671.     XtSetArg(arg[n], XmNorientation, XmHORIZONTAL); n++;
  672.     m->hsep = XmCreateSeparator(m->form, "horizontalSeparator", arg, n);
  673.     XtManageChild(m->hsep);
  674.  
  675.     /*
  676.      * Flat button
  677.      */
  678.     if (slinfo[SOUND_MIXER_BASS].supp || slinfo[SOUND_MIXER_TREBLE].supp) {
  679.         xs = XmStringCreateSimple("Flat");
  680.         n = 0;
  681.         XtSetArg(arg[n], XmNleftAttachment,
  682.              XmATTACH_OPPOSITE_WIDGET); n++;
  683.         XtSetArg(arg[n], XmNrightAttachment,
  684.              XmATTACH_OPPOSITE_WIDGET); n++;
  685.         XtSetArg(arg[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  686.         XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++;
  687.         if (slinfo[SOUND_MIXER_BASS].supp) {
  688.             XtSetArg(arg[n], XmNleftWidget,
  689.                  m->sl[SOUND_MIXER_BASS].widget_l); n++;
  690.             XtSetArg(arg[n], XmNtopWidget,
  691.                  m->sl[SOUND_MIXER_BASS].widget_lock_btn); n++;
  692.         }
  693.         else {
  694.             XtSetArg(arg[n], XmNleftWidget,
  695.                  m->sl[SOUND_MIXER_TREBLE].widget_l); n++;
  696.             XtSetArg(arg[n], XmNtopWidget,
  697.                  m->sl[SOUND_MIXER_TREBLE].widget_lock_btn); n++;
  698.         }
  699.         if (slinfo[SOUND_MIXER_TREBLE].supp) {
  700.             XtSetArg(arg[n], XmNrightWidget,
  701.                  m->sl[SOUND_MIXER_TREBLE].widget_r); n++;
  702.             XtSetArg(arg[n], XmNtopWidget,
  703.                  m->sl[SOUND_MIXER_TREBLE].widget_lock_btn); n++;
  704.         }
  705.         else {
  706.             XtSetArg(arg[n], XmNrightWidget,
  707.                  m->sl[SOUND_MIXER_BASS].widget_r); n++;
  708.             XtSetArg(arg[n], XmNtopWidget,
  709.                  m->sl[SOUND_MIXER_BASS].widget_lock_btn); n++;
  710.         }
  711.         XtSetArg(arg[n], XmNlabelString, xs); n++;
  712.         m->flat_btn = XmCreatePushButton(m->form, "flatButton", arg, n);
  713.         XtManageChild(m->flat_btn);
  714.         XmStringFree(xs);
  715.     }
  716.  
  717.     /*
  718.      * Mute button
  719.      */
  720.     if (m->mute_supp) {
  721.         xs = XmStringCreateSimple("Mute");
  722.         n = 0;
  723.         XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
  724.         XtSetArg(arg[n], XmNrightAttachment, XmATTACH_NONE); n++;
  725.         XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  726.         XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
  727.         XtSetArg(arg[n], XmNleftOffset, form_width - 100); n++;
  728.         XtSetArg(arg[n], XmNtopPosition, 87); n++;
  729.         XtSetArg(arg[n], XmNbottomPosition, 92); n++;
  730.         XtSetArg(arg[n], XmNwidth, 66); n++;
  731.         XtSetArg(arg[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  732.         XtSetArg(arg[n], XmNlabelString, xs); n++;
  733.         m->mute_btn = XmCreateToggleButton(
  734.             m->form, "muteButton", arg, n
  735.         );
  736.         XtManageChild(m->mute_btn);
  737.         XmStringFree(xs);
  738.     }
  739.  
  740.     /*
  741.      * Loudness button
  742.      */
  743.     if (m->loud_supp) {
  744.         xs = XmStringCreateSimple("Loudness");
  745.         n = 0;
  746.         XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
  747.         XtSetArg(arg[n], XmNrightAttachment, XmATTACH_NONE); n++;
  748.         XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  749.         XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
  750.         XtSetArg(arg[n], XmNleftOffset, form_width - 100); n++;
  751.         XtSetArg(arg[n], XmNtopPosition, 92); n++;
  752.         XtSetArg(arg[n], XmNbottomPosition, 97); n++;
  753.         XtSetArg(arg[n], XmNwidth, 66); n++;
  754.         XtSetArg(arg[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  755.         XtSetArg(arg[n], XmNlabelString, xs); n++;
  756.         m->loud_btn = XmCreateToggleButton(
  757.             m->form, "loudnessButton", arg, n
  758.         );
  759.         XtManageChild(m->loud_btn);
  760.         XmStringFree(xs);
  761.     }
  762.  
  763.     /*
  764.      * Enhance option menu
  765.      */
  766.     if (m->enh_supp) {
  767.         m->enh_mnu = XmCreatePulldownMenu(
  768.             m->form, "enhancePulldownMenu", NULL, 0
  769.         );
  770.  
  771.         for (i = 0; i < NENHANCE; i++) {
  772.             sprintf(wname, "enhanceButton%d", i);
  773.             sprintf(str, "%d", i);
  774.             xs = XmStringCreateSimple(str);
  775.             n = 0;
  776.             XtSetArg(arg[n], XmNlabelString, xs); n++;
  777.             m->enh_btn[i] = XmCreatePushButton(
  778.                 m->enh_mnu, wname, arg, n
  779.             );
  780.             XtManageChild(m->enh_btn[i]);
  781.             XmStringFree(xs);
  782.         }
  783.  
  784.         xs = XmStringCreateSimple("Enhance");
  785.         n = 0;
  786.         XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
  787.         XtSetArg(arg[n], XmNrightAttachment, XmATTACH_NONE); n++;
  788.         XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  789.         XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++;
  790.         XtSetArg(arg[n], XmNleftOffset, 28); n++;
  791.         XtSetArg(arg[n], XmNtopPosition, 88); n++;
  792.         XtSetArg(arg[n], XmNsubMenuId, m->enh_mnu); n++;
  793.         m->enh_opt = XmCreateOptionMenu(
  794.             m->form, "enhanceOptionMenu", arg, n
  795.         );
  796.         XtVaSetValues(
  797.             XmOptionLabelGadget(m->enh_opt),
  798.             XmNlabelString, xs,
  799.             NULL
  800.         );
  801.         XtManageChild(m->enh_opt);
  802.         XmStringFree(xs);
  803.     }
  804.  
  805.     /*
  806.      * File selection box form
  807.      */
  808.     n = 0;
  809.     XtSetArg(arg[n], XmNresizePolicy, XmRESIZE_NONE); n++;
  810.     XtSetArg(arg[n], XmNautoUnmanage, False); n++;
  811.     XtSetArg(arg[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
  812.     XtSetArg(arg[n], XmNwidth, 330); n++;
  813.     XtSetArg(arg[n], XmNheight, 370); n++;
  814.     m->fsform = XmCreateFormDialog(
  815.         m->toplevel, "fileSelectionForm", arg, n
  816.     );
  817.  
  818.     /*
  819.      * File selection box
  820.      */
  821.     xs = XmStringCreateSimple("*.mxr");
  822.     n = 0;
  823.     XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
  824.     XtSetArg(arg[n], XmNrightAttachment, XmATTACH_FORM); n++;
  825.     XtSetArg(arg[n], XmNtopAttachment, XmATTACH_FORM); n++;
  826.     XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  827.     XtSetArg(arg[n], XmNmustMatch, False); n++;
  828.     XtSetArg(arg[n], XmNpattern, xs); n++;
  829.     m->fsbox = XmCreateFileSelectionBox(
  830.         m->fsform, "fileSelectionBox", arg, n
  831.     );
  832.     XtUnmanageChild(
  833.         XmFileSelectionBoxGetChild(m->fsbox, XmDIALOG_HELP_BUTTON)
  834.     );
  835.     XtManageChild(m->fsbox);
  836.     XmStringFree(xs);
  837.  
  838.     XmStringFree(xs_left);
  839.     XmStringFree(xs_right);
  840.     XmStringFree(xs_lock);
  841.     XmStringFree(xs_rec);
  842.  
  843.     /*
  844.      * Man page window widgets
  845.      */
  846.  
  847.     /* Create form widget as container */
  848.     xs = XmStringCreateSimple("Xmmix Help");
  849.     n = 0;
  850.     XtSetArg(arg[n], XmNdialogTitle, xs); n++;
  851.     XtSetArg(arg[n], XmNautoUnmanage, True); n++;
  852.     XtSetArg(arg[n], XmNresizePolicy, XmRESIZE_NONE); n++;
  853.     XtSetArg(arg[n], XmNwidth, 460); n++;
  854.     XtSetArg(arg[n], XmNheight, 340); n++;
  855.     m->helpform = XmCreateFormDialog(m->form, "helpForm", arg, n);
  856.     XmStringFree(xs);
  857.  
  858.     /* Create text widget as help text viewer */
  859.     n = 0;
  860.     XtSetArg(arg[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  861.     XtSetArg(arg[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  862.     XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  863.     XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
  864.     XtSetArg(arg[n], XmNleftPosition, 2); n++;
  865.     XtSetArg(arg[n], XmNrightPosition, 98); n++;
  866.     XtSetArg(arg[n], XmNtopPosition, 4); n++;
  867.     XtSetArg(arg[n], XmNbottomPosition, 81); n++;
  868.     XtSetArg(arg[n], XmNeditable, False); n++;
  869.     XtSetArg(arg[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
  870.     XtSetArg(arg[n], XmNcursorPositionVisible, False); n++;
  871.     XtSetArg(arg[n], XmNcursorPosition, 0); n++;
  872.     m->helptxt = XmCreateScrolledText(m->helpform, "helpText", arg, n);
  873.     XtManageChild(m->helptxt);
  874.  
  875.     /* Create separator bar widget */
  876.     n = 0;
  877.     XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
  878.     XtSetArg(arg[n], XmNrightAttachment, XmATTACH_FORM); n++;
  879.     XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  880.     XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++;
  881.     XtSetArg(arg[n], XmNleftOffset, 2); n++;
  882.     XtSetArg(arg[n], XmNrightOffset, 2); n++;
  883.     XtSetArg(arg[n], XmNtopPosition, 84); n++;
  884.     m->helpsep = XmCreateSeparator(m->helpform, "helpSeparator", arg, n);
  885.     XtManageChild(m->helpsep);
  886.  
  887.     /* Create pushbutton widget as OK button */
  888.     xs = XmStringCreateSimple("OK");
  889.     n = 0;
  890.     XtSetArg(arg[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  891.     XtSetArg(arg[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  892.     XtSetArg(arg[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  893.     XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_NONE); n++;
  894.     XtSetArg(arg[n], XmNleftPosition, 44); n++;
  895.     XtSetArg(arg[n], XmNrightPosition, 56); n++;
  896.     XtSetArg(arg[n], XmNtopPosition, 89); n++;
  897.     XtSetArg(arg[n], XmNlabelString, xs); n++;
  898.     m->helpok_btn = XmCreatePushButton(
  899.         m->helpform, "helpOkButton", arg, n
  900.     );
  901.     XtManageChild(m->helpok_btn);
  902.     XmStringFree(xs);
  903.  
  904.     /*
  905.      * Info dialog widget for the About popup
  906.      */
  907.     xs = XmStringCreateSimple("About");
  908.     n = 0;
  909.     XtSetArg(arg[n], XmNdialogTitle, xs); n++;
  910.     XtSetArg(arg[n], XmNdialogStyle, XmDIALOG_MODELESS); n++;
  911.     m->about = XmCreateInformationDialog(
  912.         m->toplevel, "aboutDialog", arg, n
  913.     );
  914.     XtUnmanageChild(
  915.         XmMessageBoxGetChild(m->about, XmDIALOG_HELP_BUTTON)
  916.     );
  917.     XtUnmanageChild(
  918.         XmMessageBoxGetChild(m->about, XmDIALOG_CANCEL_BUTTON)
  919.     );
  920.     XmStringFree(xs);
  921.  
  922.     /*
  923.      * Info dialog widget for warning popups
  924.      */
  925.     xs = XmStringCreateSimple("Warning");
  926.     n = 0;
  927.     XtSetArg(arg[n], XmNdialogTitle, xs); n++;
  928.     XtSetArg(arg[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
  929.     m->warning = XmCreateWarningDialog(
  930.         m->toplevel, "warningDialog", arg, n
  931.     );
  932.     XtUnmanageChild(
  933.         XmMessageBoxGetChild(m->warning, XmDIALOG_HELP_BUTTON)
  934.     );
  935.     XtUnmanageChild(
  936.         XmMessageBoxGetChild(m->warning, XmDIALOG_CANCEL_BUTTON)
  937.     );
  938.     XmStringFree(xs);
  939. }
  940.  
  941.  
  942. /*
  943.  * post_realize_config
  944.  *    Top-level function to perform set-up and initialization tasks
  945.  *    after realizing all widgets.
  946.  *
  947.  * Args:
  948.  *    m - Pointer to the main widgets structure
  949.  *
  950.  * Return:
  951.  *    Nothing
  952.  */
  953. void
  954. post_realize_config(widgets_t *m)
  955. {
  956.     int    i, n;
  957.     Display    *display = XtDisplay(m->toplevel);
  958.     Pixmap    px;
  959.     char    title[STR_BUF_SZ],
  960.         *p;
  961.  
  962.     /* Set main window title bar string */
  963.     if (app_data.demo)
  964.         strcpy(title, "Motif Audio Mixer (Demo)");
  965.     else {
  966.         n = 0;
  967.         if ((i = strlen(app_data.device)) > 0) {
  968.             /* Find mixer device number */
  969.             p = app_data.device + i;
  970.             while (p > app_data.device) {
  971.                 if (!isdigit(*(p - 1)))
  972.                     break;
  973.                 p--;
  974.             }
  975.             if (isdigit(*p))
  976.                 n = atoi(p);
  977.         }
  978.         sprintf(title, "Motif Audio Mixer %d", n);
  979.     }
  980.     XStoreName(display, XtWindow(m->toplevel), title);
  981.  
  982.     /*
  983.      * Create logo pixmap
  984.      */
  985.     px = bm_to_px(m->logolbl, xmmix_bits, xmmix_width, xmmix_height, 1);
  986.     XtVaSetValues(m->toplevel, XmNiconPixmap, px, NULL);
  987.  
  988.     px = bm_to_px(m->logolbl, xmmix_bits, xmmix_width, xmmix_height,
  989.               DefaultDepth(display, DefaultScreen(display)));
  990.     XtVaSetValues(m->logolbl, XmNlabelPixmap, px, NULL);
  991.     XtVaSetValues(m->about, XmNsymbolPixmap, px, NULL);
  992.  
  993.     /* Get WM_DELETE_WINDOW atom */
  994.     delw = XmInternAtom(display, "WM_DELETE_WINDOW", False);
  995. }
  996.  
  997.  
  998. /*
  999.  * register_callbacks
  1000.  *    Top-level function to register all callback routines.
  1001.  *
  1002.  * Args:
  1003.  *    m - Pointer to the main widgets structure
  1004.  *
  1005.  * Return:
  1006.  *    Nothing
  1007.  */
  1008. void
  1009. register_callbacks(widgets_t *m)
  1010. {
  1011.     int    i;
  1012.  
  1013.     /*
  1014.      * Main window callbacks
  1015.      */
  1016.  
  1017.     /* Callbacks for each control group */
  1018.     for (i = 0; i < maxdevs; i++) {
  1019.         if (!slinfo[i].supp)
  1020.             continue;
  1021.  
  1022.         /* Left Slider callbacks */
  1023.         XtAddCallback(slinfo[i].widget_l,
  1024.             XmNvalueChangedCallback,
  1025.             (XtCallbackProc) mx_slider_l, (XtPointer) i
  1026.         );
  1027.         XtAddCallback(slinfo[i].widget_l,
  1028.             XmNdragCallback,
  1029.             (XtCallbackProc) mx_slider_l, (XtPointer) i
  1030.         );
  1031.  
  1032.         /* Right Slider callbacks */
  1033.         XtAddCallback(slinfo[i].widget_r,
  1034.             XmNvalueChangedCallback,
  1035.             (XtCallbackProc) mx_slider_r, (XtPointer) i
  1036.         );
  1037.         XtAddCallback(slinfo[i].widget_r,
  1038.             XmNdragCallback,
  1039.             (XtCallbackProc) mx_slider_r, (XtPointer) i
  1040.         );
  1041.  
  1042.         /* Lock button callback */
  1043.         XtAddCallback(slinfo[i].widget_lock_btn,
  1044.             XmNvalueChangedCallback,
  1045.             (XtCallbackProc) mx_lock_btn, (XtPointer) i
  1046.         );
  1047.  
  1048.         /* Rec button callback */
  1049.         if (slinfo[i].recsupp) {
  1050.             XtAddCallback(slinfo[i].widget_rec_btn,
  1051.                 XmNvalueChangedCallback,
  1052.                 (XtCallbackProc) mx_rec_btn, (XtPointer) i
  1053.             );
  1054.         }
  1055.     }
  1056.  
  1057.     /* Flat button callback */
  1058.     if (slinfo[SOUND_MIXER_BASS].supp || slinfo[SOUND_MIXER_TREBLE].supp) {
  1059.         XtAddCallback(m->flat_btn,
  1060.             XmNactivateCallback,
  1061.             (XtCallbackProc) mx_flat_btn, NULL
  1062.         );
  1063.     }
  1064.  
  1065.     /* Mute button callback */
  1066.     if (m->mute_supp) {
  1067.         XtAddCallback(m->mute_btn,
  1068.             XmNvalueChangedCallback,
  1069.             (XtCallbackProc) mx_mute_btn, NULL
  1070.         );
  1071.     }
  1072.  
  1073.     /* Loudness button callback */
  1074.     if (m->loud_supp) {
  1075.         XtAddCallback(m->loud_btn,
  1076.             XmNvalueChangedCallback,
  1077.             (XtCallbackProc) mx_loud_btn, NULL
  1078.         );
  1079.     }
  1080.  
  1081.     /* Stereo enhance button callbacks */
  1082.     if (m->enh_supp) {
  1083.         for (i = 0; i < NENHANCE; i++) {
  1084.             XtAddCallback(m->enh_btn[i],
  1085.                 XmNactivateCallback,
  1086.                 (XtCallbackProc) mx_enhance_btn, (XtPointer) i
  1087.             );
  1088.         }
  1089.     }
  1090.  
  1091.     /* Load button callback */
  1092.     XtAddCallback(file_pd.btip[PD_FILE_LOAD].widget,
  1093.         XmNactivateCallback,
  1094.         (XtCallbackProc) mx_load, NULL
  1095.     );
  1096.  
  1097.     /* Save button callback */
  1098.     XtAddCallback(file_pd.btip[PD_FILE_SAVE].widget,
  1099.         XmNactivateCallback,
  1100.         (XtCallbackProc) mx_save, NULL
  1101.     );
  1102.  
  1103.     /* Exit button callback */
  1104.     XtAddCallback(file_pd.btip[PD_FILE_EXIT].widget,
  1105.         XmNactivateCallback,
  1106.         (XtCallbackProc) mx_exit, NULL
  1107.     );
  1108.  
  1109.     /* Reset button callback */
  1110.     XtAddCallback(opts_pd.btip[PD_OPTS_RESET].widget,
  1111.         XmNactivateCallback,
  1112.         (XtCallbackProc) mx_reset, NULL
  1113.     );
  1114.  
  1115.     /* Man Page button callback */
  1116.     XtAddCallback(help_pd.btip[PD_HELP_MANPG].widget,
  1117.         XmNactivateCallback,
  1118.         (XtCallbackProc) mx_manpg, NULL
  1119.     );
  1120.  
  1121.     /* About button callback */
  1122.     XtAddCallback(help_pd.btip[PD_HELP_ABOUT].widget,
  1123.         XmNactivateCallback,
  1124.         (XtCallbackProc) mx_about, NULL
  1125.     );
  1126.  
  1127.     /*
  1128.      * File Selection Box callbacks
  1129.      */
  1130.  
  1131.     /* OK button callback */
  1132.     XtAddCallback(m->fsbox,
  1133.         XmNokCallback,
  1134.         (XtCallbackProc) mx_fsok_btn, NULL
  1135.     );
  1136.  
  1137.     /* Cancel button callback */
  1138.     XtAddCallback(m->fsbox,
  1139.         XmNcancelCallback,
  1140.         (XtCallbackProc) mx_fscancel_btn, NULL
  1141.     );
  1142.  
  1143.     /*
  1144.      * Focus change callback
  1145.      */
  1146.     XtAddCallback(m->form,
  1147.         XmNfocusCallback,
  1148.         (XtCallbackProc) mx_focuschg, (XtPointer) m->form
  1149.     );
  1150.  
  1151.     /*
  1152.      * Install WM_DELETE_WINDOW handler
  1153.      */
  1154.     XmAddWMProtocolCallback(
  1155.         m->toplevel,
  1156.         delw,
  1157.         (XtCallbackProc) mx_exit, (XtPointer) NULL
  1158.     );
  1159. }
  1160.  
  1161.  
  1162.